package ldh.im.web.config;

import ldh.im.web.pojo.Authority;
import ldh.im.web.pojo.Role;
import ldh.im.web.pojo.User;
import ldh.im.web.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;

/**
 * @author: ldh
 * @date: 2021-06-27 20:30:09
 */
public class AuthRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    //认证.登录
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken utoken=(UsernamePasswordToken) token;//获取用户输入的token
        String username = utoken.getUsername();
        User user = userService.getByUserName(username);
        if (user != null) {
            //放入shiro.调用CredentialsMatcher检验密码
            return new SimpleAuthenticationInfo(username, user.getPassword(), ByteSource.Util.bytes(user.getSalt()), getName());
        }
        return null;
      }

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
        List<String> permissions=new ArrayList<>();
        // 因为非正常退出，即没有显式调用 SecurityUtils.getSubject().logout()
        // (可能是关闭浏览器，或超时)，但此时缓存依旧存在(principals)，所以会自己跑到授权方法里。
        if (!SecurityUtils.getSubject().isAuthenticated()) {
            doClearCache(principal);
            SecurityUtils.getSubject().logout();
            return null;
        }
        Object shiroUser = principal.getPrimaryPrincipal();
        Subject subject =  SecurityUtils.getSubject();//获取session中的用户
        User user = (User) subject.getSession().getAttribute("LoginUser");
        if (user == null) {
            user = userService.getByUserName(shiroUser.toString());
            subject.getSession().setAttribute("LoginUser", user);
        }
        List<Role> roles = user.getRoles();
        if(roles.size()>0) {
            for(Role role : roles) {
                List<Authority> authorities = role.getAuthoritys();
                if(authorities.size()>0) {
                    for(Authority authority : authorities) {
                        permissions.add(authority.getName());
                    }
                }
            }
        }
        SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
        info.addStringPermissions(permissions);//将权限放入shiro中.
        return info;
    }

}
